package es.uned.etsii.si3.taller.servlets;

import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Map;
import java.math.BigDecimal;

import org.apache.struts2.interceptor.SessionAware;

import com.j256.ormlite.stmt.QueryBuilder;
import com.j256.ormlite.stmt.Where;
import com.opensymphony.xwork2.ActionSupport;

import es.uned.etsii.si3.taller.*;
import es.uned.etsii.si3.taller.misc.ProporcionaFuncionalidad;

public class PTFacturar extends ActionSupport implements SessionAware {

	private static final long serialVersionUID = 1L;
	
	private 	ParteTrabajo			parteSeleccionado = null;
	public 		ParteTrabajo			getParteSeleccionado() 					{ return this.parteSeleccionado; }
	public 		void					setParteSeleccionado(ParteTrabajo pT) 	{ this.parteSeleccionado = pT; }

	private 	int						parteFacturado = 0;
	public 		int						getParteFacturado() 					{ return this.parteFacturado; }
	public 		void					setParteFacturado(int pT) 				{ this.parteFacturado = pT; }

	private 	List<ParteTrabajo>		listaPartes;		
	public		List<ParteTrabajo>		getListaPartes() 						{ return this.listaPartes; }
	public 		void					setListaPartes(List<ParteTrabajo> l)	{ this.listaPartes = l; }

	private 	int						parteTrabajoSel = -1;
	public 		int						getParteTrabajoSel () 					{ return this.parteTrabajoSel; }
	public		void					setParteTrabajoSel (int parteTrabajoSel){ this.parteTrabajoSel = parteTrabajoSel; }
	
	private 	List<Reparacion>		reparacionesTrabajo;
	public		List<Reparacion>		getReparacionesTrabajo()				{return this.reparacionesTrabajo; }
	public		void					setReparacionesTrabajo(List<Reparacion> rt){this.reparacionesTrabajo = rt; }

	private 	List<Trabajo>			trabajosParte;
	public		List<Trabajo>			getTrabajosParte()						{return this.trabajosParte; }
	public		void					setTrabajosParte(List<Trabajo> tr)		{this.trabajosParte = tr; }
	
	private 	List<MaterialTrabajo>	matTrabajo;
	public		List<MaterialTrabajo>	getMatTrabajo()							{return this.matTrabajo; }
	public		void					setMatTrabajo(List<MaterialTrabajo> mt)	{this.matTrabajo = mt; }

	private		String					fechaSalida = null;
	public		String					getFechaSalida()						{ return this.fechaSalida; }
	public		void					setFechaSalida (String fs)				{this.fechaSalida = fs; }

	private 	String					precioFinal=null;
	public		String					getPrecioFinal()						{return this.precioFinal; }
	public		void					setPrecioFinal(String precioFinal)		{ this.precioFinal = precioFinal; }
	
	private 	Map<String, Object>	userSession;

	/**
	 * Muestra los datos de la factura del parte seleccionado
	 * @return  actionerror
	 */
	@ProporcionaFuncionalidad(identificador = FactoriaFunciones.JEFE_TALLER_FACTURAR_TRABAJO)	
	public String pTMostrarFactura() {
		String res = SUCCESS;
		try {
			// Recuperamos el parte de trabajo a facturar
			parteSeleccionado = FactoriaDAO.recuperar(ParteTrabajo.class, parteTrabajoSel);
			
			// Obtenemos todas las reparaciones
			QueryBuilder<Reparacion, Integer> repQb = FactoriaDAO.getDao(Reparacion.class).queryBuilder();
			repQb.where().eq(Reparacion.ID_PARTETRABAJO_FIELD_NAME, parteTrabajoSel);
			reparacionesTrabajo = repQb.query();
			// Obtenemos todos los trabajos
			
			QueryBuilder<Trabajo, Integer> trabQb = FactoriaDAO.getDao(Trabajo.class).queryBuilder();
			trabajosParte = trabQb.join(repQb).query();
			
			// Obtenemos todos los materiales
			QueryBuilder<MaterialTrabajo, Integer> matQb = 
					FactoriaDAO.getDao(MaterialTrabajo.class).queryBuilder();
			matTrabajo = matQb.join(trabQb).query();
			
		} catch (SQLException e) {
			addActionError("Error de base de datos: " + e);
			res = ERROR;
		}
		return res;
	}
	
	/**
	 * Muestra la lista de partes que se pueden facturar
	 * @return  actionerror
	 */
	@ProporcionaFuncionalidad(identificador = FactoriaFunciones.JEFE_TALLER_FACTURAR_TRABAJO)	
	public String pTCargarFactura() {
		String res = SUCCESS;
		try {
			QueryBuilder<ParteTrabajo, Integer> parteQb = 
					FactoriaDAO.getDao(ParteTrabajo.class).queryBuilder();
			Where<ParteTrabajo, Integer> wParteQb = parteQb.where();
			wParteQb.eq(ParteTrabajo.ID_TALLER_FIELD_NAME, this.getTallerSesionEmpleado());
			wParteQb.and().eq(ParteTrabajo.VISTOBUENO_FIELD_NAME, true);
			wParteQb.and().isNull(ParteTrabajo.FECHASALIDA_FIELD_NAME);
			wParteQb.and().eq(ParteTrabajo.AVISADO_FIELD_NAME,true);
			List<ParteTrabajo> lista = wParteQb.query();
			this.setListaPartes(lista);
		} catch (SQLException e) {
			addActionError("Error al localizar los trabajos por facturar: " + e);
			res = ERROR;
		}		
		return res;
	}
	
	/**
	 * Realiza la facturación del parte
	 * @return  actionerror
	 */
	@ProporcionaFuncionalidad(identificador = FactoriaFunciones.JEFE_TALLER_FACTURAR_TRABAJO)	
	public String facturar() {
		String res=SUCCESS;
		SimpleDateFormat df = new SimpleDateFormat("dd/MM/yy"); 

		try {
		// Lo volvemos a cargar para que no se pierda
			parteSeleccionado = FactoriaDAO.recuperar(ParteTrabajo.class, parteFacturado);

			parteSeleccionado.setFechaSalida(df.parse(fechaSalida));
			parteSeleccionado.setPrecioFinal(new BigDecimal(precioFinal));
			parteSeleccionado.update();
			parteSeleccionado.refresh();
		}
		catch (SQLException e) {
			addActionError("Error al hacer el update");
			setParteTrabajoSel(parteFacturado);
			res = pTMostrarFactura();
			res = INPUT;
		}
		catch (ParseException e) {
			addActionError("Error al comprobar la fecha");			
			setParteTrabajoSel(parteFacturado);
			res = pTMostrarFactura();
			res = INPUT;
		} 
		catch (NullPointerException e) {
			addActionError("Error de puntero nulo");
			setParteTrabajoSel(parteFacturado);
			res = pTMostrarFactura();
			res = INPUT;
		}
	return res;
	}
	
	private Taller getTallerSesionEmpleado() {
		Taller res = null;
		Usuario uS = (Usuario) userSession.get("usuario");
		QueryBuilder<EmpleadoTaller, Integer> eTQb;
		try {
			eTQb = FactoriaDAO.getDao(EmpleadoTaller.class).queryBuilder();
			Where<EmpleadoTaller, Integer> wETQb = eTQb.where();			
			wETQb.eq(EmpleadoTaller.ID_USUARIO_FIELD_NAME, uS.getId());			
			List<EmpleadoTaller> lista = wETQb.query();
			res = lista.get(0).getTaller();
		} catch (SQLException e) {
			addActionError("Error al buscar taller: " + e);
		}			
		return res;
	}

	
	@Override
	public void setSession(Map<String, Object> session) {
		userSession = session;		
	}

}
